4  H-Brücke

Code
##| echo: false

import pandas as pd
from plotly.subplots import make_subplots
import plotly.express as px
import plotly.graph_objects as go

def trans_plot(filepath, thing_to_plot):
    df = pd.read_csv(filepath,sep=';',decimal=',')

    for key in thing_to_plot:
        suplotnumber_max = 0
        if max(thing_to_plot[key]) > 0:
            suplotnumber_max = max(thing_to_plot[key])

    fig = make_subplots(
        rows=suplotnumber_max, cols=1,
    )

    for key in thing_to_plot:
        for i in thing_to_plot[key]:
            fig.add_trace(go.Scatter(x=df.time.values, y=df[key].values,name=key), row=thing_to_plot[key][0], col=1)
            fig.update_xaxes(title_text=None, tickformat = ".3s", ticksuffix="s",  row=thing_to_plot[key][0], col=1)
            if key[0] == 'v':
                ticksuff = 'V'
            elif key[0] == 'i':
                ticksuff = 'A'
            else:
                ticksuff = ''
            fig.update_yaxes(title=key, ticksuffix=ticksuff,tickformat = ".3s", row=thing_to_plot[key][0], col=1)

    fig.update_layout(
        hovermode="x unified",
        legend_title=None,

        font=dict(
            family="Arial",
            size=12,
            color="black"
        ),
        legend=dict(
            orientation="h",
            yanchor="top",
            y=-0.15,
            xanchor="left",
            x=0.01
        ),
        height=1000/8*suplotnumber_max,
        width=800,
    )

    fig.write_image(filepath.replace('.csv','.svg'))
    fig.show()
Code
#import sys
# adding Folder_2 to the system path
#sys.path.insert(0, '../../../Common/QuartoBookHelpers')
#import QuartoBookHelpers

from IPython.display import Markdown, Latex

from sympy import *
import sympy.physics.units as u
import numpy as np
from matplotlib import pyplot as plt
from quantiphy import Quantity
import re

class MySymbol(Symbol):
    def __new__(cls, name, description='',unit='',value=''):
        obj = Symbol.__new__(cls, name)
        obj.description = description
        obj.unit = unit
        obj.value = value
        
        return obj

class MyFunction(Function):
    def __new__(cls, name, description='',unit='',value=''):
        obj = Function.__new__(cls, name)
        obj.description = description
        obj.unit = unit
        obj.value = value
        
        return obj
        
class QBookHelpers():
    def print_description(dic):
        for vari in dic:
            display(Markdown(f'${latex(vari)}$' + ' ... ' + vari.description))
            
    def print_equation(eq,**kwargs):
        #print(kwargs)
        if kwargs != {}:
            label = kwargs['label']
            #print(label)
            display(Markdown(f'$$\n{latex(eq)}\n$${{#' + label + f'}}'))
        else:      
            display(Markdown(f'$$\n{latex(eq)}\n$${{#eq-Dummy}}'))
            
    def print_values(dic,**kwargs):
        for vari in dic:
            try:
                QuantValue = Quantity(vari.value,str(vari.unit.abbrev))
            except:
                QuantValue = Quantity(vari.value)
            
            quant_string = QuantValue.render(prec=2)
            val = quant_string.split(' ')[0]
            if quant_string[-1].isdigit():
                uni = ''
            else:
                try:
                    uni = quant_string.split(' ')[1]
                except:
                    uni = quant_string[-1]
            #print(re.split('(\d+)',QuantValue.render(prec=2)))
            #uni = re.split('(\d+)',QuantValue.render(prec=2))[-1]
            #uni = ''
            #val = re.split('(\d+)',QuantValue.render(prec=2))[1]
            #val = QuantValue.render(prec=2)

            if uni.find('ohm') >=0:
                uni = '\ \mathrm{' + uni.replace('ohm','\Omega') + '}'
                disp_string = f'$${latex(vari)}' + ' = ' + latex(val) + ' ' + str(uni) + f'$$' 
            else:
                disp_string = f'$${latex(vari)}' + ' = ' + latex(val) + ' \ ' + latex(uni) + f'$$' 
            
            if kwargs != {}:
                label = kwargs['label']
                disp_string = disp_string + f'{{#' + label + f'}}'

            
            display(Markdown(disp_string))

            #display(Markdown(f'${latex(vari)}$' + ' = ' + str(vari.value) + f'$\ {latex(vari.unit)}$' ))            
            #display(Markdown(f'${latex(vari)}$' + ' = ' + str("%.2f" % round(vari.value, 2)) + f'$\ {latex(vari.unit)}$' ))
            #display(Markdown(f'$${latex(vari)}' + ' = ' + latex(QuantValue.render()) + f'$$' ))
            #display(Markdown(f'$${latex(vari)}' + ' = ' + latex(quant) + f'$$' ))
            #display(Markdown(f'$${latex(vari)}' + ' = ' + str(vari.value) + f'\ {latex(vari.unit)}$$' ))

            
    def calculate_num_value(eqn):
        replacement = {}
        for sym in eqn.rhs.free_symbols:
            case = {sym:sym.value}
            replacement.update(case)
        #print(replacement)
        #return Eq(eqn.lhs,eqn.rhs.evalf(subs=replacement))
        eqn.lhs.value = eqn.rhs.evalf(subs=replacement)
        #display(eqn.lhs.value)

    def logic_parser(eqn):
        return str(eqn).replace('&','and').replace('|','or').replace('~','not')

Der Markt für DC-Motoren belief sich im Jahr 2022 auf ca. 20,1 Milliarden US-Dollar und es wurde erwartet, dass sich das Volumen bis 2031 auf 49,3 Milliarden erhöht [1]. Jeder dieser Motoren braucht eine mehr oder weniger komplizierte Ansteuerung. Eine mögliche Ansteuerung soll hier gezeigt werden.

Ziel
Es soll eine Schaltung entworfen werden welche es erlaubt, einen DC-Motor in folgenden Betriebsarten zu betreiben:

Bei den ersten beiden Punkten soll es Möglich sein, die Drehzahl mittels Puls-Weiten-Modulation (PWM) zu ändern.

Lernziele

Hilfestellung

Hierarchisches Design

4.1 Beschreibung der H-Brücke

Im einfachsten Fall wird die Stromversorgung, welche eine entsprechende Leistung hat, mit einem Schalter eingeschaltet und der Motor dreht sich. Um einen Motor drehzahlgesteuert zu betreiben, bedarf es ein Steuersignal und der entsprechenden Leistung für den Motor. In den meisten Fällen ist es so, dass das Steuersignal selbst nicht ausreichend Leistung hat, da es aus einem Mikrocontroller kommt.
Mit Schaltung Abbildung 2.1 kann ein Motor drehzahlgesteuert betrieben werden. Der MOSFET verstärkt dabei die Leistung des Steuersignales. Die Leistung wird von der Quelle \(U_q\) zur Verfügung gestellt. Allerdings lässt sich dabei die Drehrichtung nicht ändern.
Um die oben geforderten Betriebszustände zu erreichen, bedarf es der H-Brücke, auch Vier-Quadranten-Steller genannt, in Abbildung 4.1. Die punktiert umrandete Schaltung ist dabei das Ersatzschaltbild eines DC-Motors.

Abbildung 4.1: H-Brücke [2]

4.1.1 Funktionsweise

Für die Erklärung der Funktionsweise werden die MOSFET’s durch gedachte Schalter ersetzt. Dies ist Zulässig, da der MOSFET als Schalter betrieben werden kann. Siehe dazu Kapitel 2.1.

Abbildung 4.2: Ersatzschaltbild H-Brücke mit Schaltern

\(S_1, S_2, S_ 3\) und \(S_4\) stellen dabei Potentiale dar. Zur Erinnerung, ein MOSFET schaltet wenn die Spannung zwischen Gate und Source, \(U_{GS}\), die Threshold-Spannung \(U_{GS,Threshold}\) überschreitet.

Der Trick ist, den Stromfluss durch den Motor für Rechtslauf und Linkslauf umzukehren. Dies gelingt wie folgt.

4.1.1.1 Linkslauf

Abbildung 4.3: Ersatzschaltbild H-Brücke mit Schaltern, Linkslauf

Transistoren \(S_2\) und \(S_3\) müssen durchschalten. Transistoren \(S_1\) und \(S_4\) müssen gesperrt sein.

4.1.1.2 Rechtslauf

Abbildung 4.4: Ersatzschaltbild H-Brücke mit Schaltern, Rechtslauf

Transistoren \(S_1\) und \(S_4\) müssen durchschalten. Transistoren \(S_2\) und \(S_3\) müssen gesperrt sein.

4.1.1.3 Bremsen

Um den Motor zu bremsen muss er Kurzgeschlossen werden. Daraus ergibt sich, dass die Transistoren \(S_2\) und \(S_4\) durchgeschaltet sind und die Transistoren \(S_1\) und \(S_3\) gesperrt sind.

Abbildung 4.5: Ersatzschaltbild H-Brücke mit Schaltern, Bremsen

4.2 Entwicklung der Logik

4.2.1 Von der Wahrheitstabelle zur Booleschen Gleichung

Zunächst muss in der Zuordnungstabelle der Zusammenhang zwischen dem logischen Zustand und dem physikalischen Wert definiert werden.

Tabelle 4.1: Zuordnungstabelle
Eingang / Ausgang Bezeichnung Zuordnung Beschreibung
Eingang E … Enable 0 … Disabled; 1 … Enabled Damit wird die Schaltung Betriebsbereit, Ist Enable deaktiviert kann an den anderen Eingängen ein beliebiges Signal anliegen, der Motor darf sich trotzdem nicht bewegen.
Eingang B … Break 0 … Disabled; 1 … Enabled Aktivierung des Bremsbetriebs. Hat Vorrang über die Richtungswahl.
Eingang D … Direction 0 … Linkslauf; 1 … Rechtslauf Gibt die Drehrichtung vor.
Eingang P … PWM PWM Signal Gibt die Drehzahl vor.
Ausgänge S1, S2, S3, S4 0 … MOSFET aus; 1 … MOSFET ein Steuersignal für die Transistoren, diese entsprechen noch nicht dem benötigten Potentialen!

In der Wahrheitstabelle wird nun der Schaltzustand der Ausgänge in Abhängigkeit der Eingänge definiert.

Code
##| echo: false
#| label: #tbl-Wahrheitstabelle
#| tbl-cap: Wahrheitstabelle

import pandas as pd

df = pd.read_csv('HBrücke_Wahrheitstabelle.csv',sep=';')

display(Markdown(df.to_markdown(index=False,tablefmt="github", colalign ='center')))
PWM Enable Direction Break S1 S2 S3 S4
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0
0 0 1 1 0 0 0 0
0 1 0 0 0 0 0 0
0 1 0 1 0 1 0 1
0 1 1 0 0 0 0 0
0 1 1 1 0 1 0 1
1 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0
1 0 1 0 0 0 0 0
1 0 1 1 0 0 0 0
1 1 0 0 0 1 1 0
1 1 0 1 0 1 0 1
1 1 1 0 1 0 0 1
1 1 1 1 0 1 0 1

Mittels KV-Diagram oder Boolescher Algebra kann aus der Wahrheitstabelle die einfachste Boolesche Gleichung ermittelt werden.

Hinweis

\(\bar{A} = \neg A\)

Code
##| echo: false


from sympy.logic import SOPform
from sympy.logic.boolalg import to_cnf, to_dnf


PWM = MySymbol('P',description='PWM Eingang')
Enable = MySymbol('E',description='Enable Eingang')
Break = MySymbol('B',description='Break Eingang')
Direction = MySymbol('D',description='Direction Eingang')
Eingaenge = [PWM, Enable, Direction, Break]

S1 = MySymbol('S1',description='Steuersignal Transistor 1')
mintermsS1 = df[df['S1'].isin([1])].iloc[:,0:4].values.tolist()
#display(Eq(S1,POSform(Eingaenge, mintermsS1)))
S1eq = Eq(S1,SOPform(Eingaenge, mintermsS1))
display(S1eq)

S2 = MySymbol('S2',description='Steuersignal Transistor 2')
mintermsS2 = df[df['S2'].isin([1])].iloc[:,0:4].values.tolist()
S2eq = Eq(S2,(POSform(Eingaenge, mintermsS2)))
display(S2eq)
#display(Eq(S2,to_cnf(SOPform(Eingaenge, mintermsS2),simplify=True)))

S3 = MySymbol('S3',description='Steuersignal Transistor 3')
mintermsS3 = df[df['S3'].isin([1])].iloc[:,0:4].values.tolist()
#display(Eq(S3,POSform(Eingaenge, mintermsS3)))
S3eq = Eq(S3,SOPform(Eingaenge, mintermsS3))
display(S3eq)

S4 = MySymbol('S4',description='Steuersignal Transistor 4')
mintermsS4 = df[df['S4'].isin([1])].iloc[:,0:4].values.tolist()
S4eq = Eq(S4,POSform(Eingaenge, mintermsS4))
display(S4eq)
#display(Eq(S4,SOPform(Eingaenge, mintermsS4)))

\(\displaystyle S_{1} = D \wedge E \wedge P \wedge \neg B\)

\(\displaystyle S_{2} = E \wedge \left(B \vee P\right) \wedge \left(B \vee \neg D\right)\)

\(\displaystyle S_{3} = E \wedge P \wedge \neg B \wedge \neg D\)

\(\displaystyle S_{4} = E \wedge \left(B \vee D\right) \wedge \left(B \vee P\right)\)

Zur Überprüfung wird aus den Gleichungen die Wahrheitstabelle erstellt und mit der oben definierten Wahrheitstabelle verglichen.

Tabelle 4.2: Wahrheitstabelle Kontrolle
P E D B S1 S2 S3 S4
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0
0 0 1 1 0 0 0 0
0 1 0 0 0 0 0 0
0 1 0 1 0 1 0 1
0 1 1 0 0 0 0 0
0 1 1 1 0 1 0 1
1 0 0 0 0 0 0 0
1 0 0 1 0 0 0 0
1 0 1 0 0 0 0 0
1 0 1 1 0 0 0 0
1 1 0 0 0 1 1 0
1 1 0 1 0 1 0 1
1 1 1 0 1 0 0 1
1 1 1 1 0 1 0 1

Die Tabellen stimmen überein. Die Gleichungen sind somit richtig.

4.2.2 Schaltung

Die Logik kann mit verschiedenen Technologien umgesetzt werden. Hier wurde eine Lösung mittels TTL Gattern gewählt. Die Schaltung ist in Abbildung 4.6 dargestellt. In einer modernen Anwendung würde die Logik mittels Mikrocontroller realisiert werden. Quartus oder PSoC creator bieten hier Lösungen an. In Quartus lässt sich die Logik aus simulieren.

Hinweis

Aus wirtschaftlichen Gründen sollte eine Logikschaltung aus möglichst wenigen verschiedenen Logikgattern bestehen. Es bietet sich an, die Schaltung mit NAND oder NOR Gattern aufzubauen. Aus zeitgründen wird im Moment hier darauf verzichtet. Mit der Regel von DeMorgan kann die Schaltung in die jeweilige schreibweise übergeführt werden. \[\overline{A \land B} = \overline{A} \lor \overline{B}\] \[\overline{A \lor B} = \overline{A} \land \overline{B}\]

Abbildung 4.6: Logikschaltung mit TTL

Mittels simulation kann die Funktion der Schaltung überprüft werden. Dazu wird der zeitliche verlauf mit der Wahrheitstabelle verglichen. Stimmen die Signale überein, ist die Schaltung richtig.

Abbildung 4.7: Simulation Logikschaltung mit TTL

Der Signallaufplan passt mit der Wahrheitstabelle überein. Somit ist davon auszugehen, dass die TTL-Schaltung korrekt umgesetzt wurde.

4.3 Ansteuerung der H-Brücke

Die H-Brücke besteht aus P-Kanal Mosfets und N-Kanal Mosfets. Mosfets werden über den Potentialunterschied zwischen Gate und Source gesteuert. Bei den N-Kanal Mosfets T2 und T4 könnte direkt der Ausgang der Logikschaltung verwendet werden. Bei den P-Kanal Mosfets T1 und T3 ist dies nicht möglich, da die Logikschaltung nicht das geeignete Potential liefern kann. Die P-Kanal Mosfets sperren wenn am Gate die selbe Spannung anliegt wie am Source Eingang. Sie leiten wenn am Gate Ground anliegt. Es muss also eine Schaltung entworfen werden, welche die Potentiale anpasst. Aus der obigen Überlegung ergibt sich folgende Anforderung an die Pegelanpassung.

Ausgang TTL S1 und S3 Potential am Source Eingang
0 V \(U_s\)
5 V 0 V

Diese Anpassung lässt sich mittels OPV’s realisieren, welche mit der Zwischenkreisspannung, diese liegt am Source Eingang von T1 und T3 an, und Ground versorgt werden. Das TTL Signal wird am negativen Eingang des OPV angelegt um die invertierung zu erreichen. Der OPV verstärkt das Signal und liefert am Ausgang das gewünschte Potential. Die Schaltung ist in Abbildung 4.8 dargestellt. Da das Ausgangssignal der TTL Schaltung nicht genau 0 V beträgt wird am positiven Eingang eine Referenzspannung von 2 V angelegt. Als OPV’s müssen Rail to Rail OPV’s verwendet werden. Diese können bis auf 0 V herunter schalten. Werden andere verwendet schalten die Mosfets nicht ganz durch und es kommt zu Leistungsverlusten.

Abbildung 4.8: OPV Schaltung

4.4 Simulation der H-Brücke

Will man nun die Funktion der H-Brücke simulieren, muss die Logikschaltung mit der Pegelanpassung, die H-Brücke und das Motormodel zusammengeführt werden. Die Schaltung ist in Abbildung 4.9 dargestellt. Der Motor kann über das einfache Modell Abbildung 4.10 simuliert werden. Das erweiterte Modell Abbildung 4.11 liefert auch Informationen über die Drehzahl und das Massenträgheitsmoment, damit kann auch der Bremsvorgang betrachtet werden.

Abbildung 4.9: Zusammengeführte Schaltung

Abbildung 4.10: Einfaches Motormodel

Abbildung 4.11: Erweitertes Motormodel, [3]

Nun können die Betriebszustände simuliert werden. Die Simulation ist in Abbildung 4.12 dargestellt. Die Simulation zeigt, dass die H-Brücke wie gewünscht funktioniert. Die Drehzahl lässt sich mittels PWM verändern. Die Drehrichtung lässt sich mittels D ändern. Die Bremsfunktion lässt sich mittels B aktivieren.

Abbildung 4.12: Simulation Brücke Linkslauf, Rechtslauf und Bremsen
Abbildung 4.13: Simulation Brücke Linkslauf, Rechtslauf und Bremsen mit PWM

4.5 PWM und induktive Lasten

To Be Continued